export function fullScreen() {
  function launchFullscreen(element) {
    if(element.requestFullscreen) {
      element.requestFullscreen();
    } else if(element.mozRequestFullScreen) {
      element.mozRequestFullScreen();
    } else if(element.webkitRequestFullscreen) {
      element.webkitRequestFullscreen();
    } else if(element.msRequestFullscreen) {
      element.msRequestFullscreen();
    }
  }
  setTimeout(()=>launchFullscreen(document.documentElement), 1000)
}

export function setBrowserTitle(title) {
  document.title = title
}

export function getBrowserTitle() {
  return document.title
}

export function getAppVersion() {
  //#ifdef MP-WEIXIN
  let accountInfo = wx.getAccountInfoSync().miniProgram
  return accountInfo.version || accountInfo.envVersion || ''
  //#endif
  //#ifdef APP-PLUS
  return plus.runtime.version
  //#endif
}

export function formatUrl(url, params) {
  params = params?('?'+Object.entries(params).filter(v=>v!==undefined).map(([k,v])=>(k+'='+v)).join('&')):'';
  return url+params
}
export function parseUrl(str) {
  let [url, query] = (str||'').split('?')
  let params = {}
  query&&query.split('&').forEach(v=>{
    let [kk,vv] = v.split('=')
    params[kk] = vv
  })
  return {
    url,
    params
  }
}

export function money(value) {
  return Number(Number(value||0).toFixed(2));
}

export function moneyfen(value, defaultValue) {
  if (!Number(value)) {
    return defaultValue||'0.00'
  }
  value = value / 100.0;
  return Number(value.toFixed(2))
}

// 获取当前年月日时分秒
export function datetime(value) {
  let date = value ? new Date(value) : new Date();
  let month = date.getMonth() + 1;
  let strDate = date.getDate();
  if (month >= 1 && month <= 9) {
    month = '0' + month;
  }
  if (strDate >= 0 && strDate <= 9) {
    strDate = '0' + strDate;
  }
  //时分秒
  let hours = (date.getHours() < 10 ? '0' + (date.getHours()) : date.getHours());
  let min = (date.getMinutes() < 10 ? '0' + (date.getMinutes()) : date.getMinutes());
  let seconds = (date.getSeconds() < 10 ? '0' + (date.getSeconds()) : date.getSeconds());
  return `${date.getFullYear()}-${month}-${strDate} ${hours}:${min}:${seconds}`;
}

// 获取当前年月日
export function date(value) {
  let date = value ? new Date(value) : new Date();
  let month = date.getMonth() + 1;
  let strDate = date.getDate();
  if (month >= 1 && month <= 9) {
    month = '0' + month;
  }
  if (strDate >= 0 && strDate <= 9) {
    strDate = '0' + strDate;
  }
  return `${date.getFullYear()}-${month}-${strDate}`;
}

// 获取时间
export function time(value) {
  let date = new Date(value);
  return `${date.getHours()}:${date.getMinutes()}:${date.getSeconds()}`;
}

// 根据日期区间获取天数
export function getDateByDays(startDate, endDdate) {
	let d1 = Date.parse(new Date(startDate));
	let d2 = Date.parse(new Date(endDdate));
    // 时间戳相减 / 天数
	let day = parseInt((d2 - d1) / (1000 * 60 * 60 * 24));
	return day
}

// 获取某一日期区间 返回数组
export function rangeDays(startDate, endDdate) {
  let number = getDateByDays(startDate, endDdate)   //获取今天的日期
  let startDateTime = new Date(startDate).getTime();  
  let dateArray = []

  for(let i = 0; i < number; i++){
    // 返回时间戳
    let tsTransDate = date(startDateTime + 1000*60*60*24*i)
    dateArray.push(tsTransDate)
  }
  // console.log('日期区间dateArray',dateArray)
  return dateArray
}

// 获取未来几天内的日期 返回数组
export function futureDays(number) {
  const today = new Date()   //获取今天的日期
  let todayTime = today.getTime();  
  let dateArray = []

  for(let i = 0; i < number; i++){
    // 返回时间戳
    let tsTransDate = date(todayTime + 1000*60*60*24*i)
    dateArray.push(tsTransDate)  //获取未来7天内的日期
  }
  // console.log('dateArray',dateArray)
  return dateArray
}

// 获取几个月前的日期
export function getMonthAgoDate(numMonth) {
  const date = new Date();
  date.setMonth(date.getMonth() - numMonth);

  const year = date.getFullYear();
  const month = String(date.getMonth() + 1).padStart(2, '0'); // 月份从0开始，所以要加1
  const day = String(date.getDate()).padStart(2, '0');

  return `${year}-${month}-${day}`;
}

// 获取周几
export function week(value) {
  let weekStr = ""
  let week = new Date(value).getDay()
  if (week == 0) {
    weekStr = "星期日";
    } else if (week == 1) {
      weekStr = "星期一";
    } else if (week == 2) {
      weekStr = "星期二";
    } else if (week == 3) {
      weekStr = "星期三";
    } else if (week == 4) {
      weekStr = "星期四";
    } else if (week == 5) {
      weekStr = "星期五";
    } else if (week == 6) {
      weekStr = "星期六";
  }
  return weekStr
}

/**
 * 计算当前日期与指定日期相差的天数
 * @param {String|Date} targetDate 目标日期，支持日期对象或日期字符串
 * @returns {Number} 相差的天数，如果目标日期在今天之前则返回负数
 */
export function getDaysDiff(targetDate) {
  const today = new Date()
  today.setHours(0, 0, 0, 0)
  
  const target = new Date(targetDate)
  target.setHours(0, 0, 0, 0)
  
  const diff = target.getTime() - today.getTime()
  return Math.floor(diff / (1000 * 60 * 60 * 24))
}

// export function getDaysDiff(targetDate) {
//   const today = new Date()
//   const target = new Date(targetDate)
//   const diff = target.getTime() - today.getTime()
//   return diff / (1000 * 60 * 60 * 24)
// }

// 根据身份证号获取年龄
export function getAgeByCard(identityCard) {
  let len = (identityCard + '').length;
  if (len == 0) {
      return 0;
  } else {
    if ((len != 15) && (len != 18))//身份证号码只能为15位或18位其它不合法
    {
      return 0;
    }
  }
  let strBirthday = '';
  if (len == 18)//处理18位的身份证号码从号码中得到生日和性别代码
  {
    strBirthday = identityCard.substr(6, 4) + "/" + identityCard.substr(10, 2) + "/" + identityCard.substr(12, 2);
  }
  if (len == 15) {
    strBirthday = "19" + identityCard.substr(6, 2) + "/" + identityCard.substr(8, 2) + "/" + identityCard.substr(10, 2);
  }
  //时间字符串里，必须是“/”
  let birthDate = new Date(strBirthday);
  let nowDateTime = new Date();
  let age = nowDateTime.getFullYear() - birthDate.getFullYear();
  if (nowDateTime.getMonth() < birthDate.getMonth() || (nowDateTime.getMonth() == birthDate.getMonth() && nowDateTime.getDate() < birthDate.getDate())) {
    age--;
  }
  return age;
}

// 检测年龄范围
export function checkAgeRange(age, min, max) {
  // 检查是否为数字
  if (typeof age !== 'number') return false
  // 检查是否为整数
  if (!Number.isInteger(age)) return false
  // 检查是否在范围内
  if (age < min || age > max) return false
  
  return true
}

// 根据身份证号获取性别(1男,2女)
export function getSexByCard(identityCard) {
  let len = (identityCard + '').length;
  if (len == 0 || ((len != 15) && (len != 18))) {
    return 0;
  }
  // 15位身份证末尾一位代表性别,18位身份证倒数第二位代表性别
  let sexBit = len == 15 ? identityCard.slice(-1) : identityCard.slice(-2, -1);
  // 奇数为男,偶数为女
  return Number(sexBit) % 2 ? 1 : 2;
}

// 校验身份证号正确性及是否符合性别和年龄要求
export function validateIdCard(idCard, sex, age) {
  // 基础格式校验
  if (!/^[1-9]\d{5}(18|19|20)\d{2}((0[1-9])|(1[0-2]))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$/.test(idCard)) {
    return false;
  }
  
  // 校验性别(1男,2女) - 转换为数字进行比较
  let cardSex = getSexByCard(idCard);
  if (sex && cardSex !== Number(sex)) {
    return false;
  }
  
  // 校验年龄 - 转换为数字进行比较
  let cardAge = getAgeByCard(idCard);
  if (age && cardAge !== Number(age)) {
    return false;
  }
  
  // 校验校验码
  const coefficient = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2]; // 系数
  const lastCodeArr = ['1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2']; // 校验码对应值
  let sum = 0;
  for (let i = 0; i < 17; i++) {
    sum += Number(idCard[i]) * coefficient[i];
  }
  let lastCode = lastCodeArr[sum % 11];
  if (lastCode.toLowerCase() !== idCard[17].toLowerCase()) {
    return false;
  }
  
  return true;
}

// 根据生日获取年龄
export function getAgeByBirthday(birthday) {
  birthday=birthday.split('-');
  // 新建日期对象
  let date = new Date();
  // 今天日期，数组，同 birthday
  let today = [date.getFullYear(), date.getMonth() + 1, date.getDate()];
  // 分别计算年月日差值
  let age = today.map((val, index) => {
      return val - birthday[index]
  })
  // 当天数为负数时，月减 1，天数加上月总天数
  if (age[2] < 0) {
      // 简单获取上个月总天数的方法，不会错
      let lastMonth = new Date(today[0], today[1], 0)
      age[1]--
      age[2] += lastMonth.getDate()
  }
  // 当月数为负数时，年减 1，月数加上 12
  if (age[1] < 0) {
      age[0]--
      age[1] += 12
  }
  return Number(age)
  // var r = birthday.match(/^(\d{1,4})(-|\/)(\d{1,2})\2(\d{1,2})/);
  //   if(r==null)return   false;

  //   var d= new Date(r[1],r[3]-1,r[4]);
  //   var returnStr = "输入的日期格式错误！";

  //   if(d.getFullYear()==r[1]&&(d.getMonth()+1)==r[3]&&d.getDate()==r[4]){

  //       var date = new Date();
  //       var yearNow = date.getFullYear();
  //       var monthNow = date.getMonth() + 1;
  //       var dayNow = date.getDate();

  //       var largeMonths = [1,3,5,7,8,10,12], //大月， 用于计算天，只在年月都为零时，天数有效
  //           lastMonth = monthNow -1>0?monthNow-1:12,  // 上一个月的月份
  //           isLeapYear = false, // 是否是闰年
  //           daysOFMonth = 0;    // 当前日期的上一个月多少天

  //       if((yearNow%4===0&&yearNow%100!==0)||yearNow%400===0){  // 是否闰年， 用于计算天，只在年月都为零时，天数有效
  //           isLeapYear = true;
  //       }

  //       if(largeMonths.indexOf(lastMonth)>-1){
  //           daysOFMonth = 31;
  //       }else if(lastMonth===2){
  //           if(isLeapYear){
  //               daysOFMonth = 29;
  //           }else{
  //               daysOFMonth = 28;
  //           }
  //       }else{
  //           daysOFMonth = 30;
  //       }

  //       var Y = yearNow - parseInt(r[1]);
  //       var M = monthNow - parseInt(r[3]);
  //       var D = dayNow - parseInt(r[4]);
  //       if(D < 0){
  //           D = D + daysOFMonth; //借一个月
  //           M--;
  //       }
  //       if(M<0){  // 借一年 12个月
  //           Y--;
  //           M = M + 12; //
  //       }

  //       if(Y<0){
  //           returnStr = "出生日期有误！";

  //       }else if(Y===0){
  //           if(M===0){
  //               returnStr = D+"D";
  //           }else{
  //               returnStr = M+"M";
  //           }
  //       }else{
  //           if(M===0){
  //               returnStr = Y+"Y";
  //           }else{
  //               returnStr = Y+"Y"+M+"M";
  //           }
  //       }

  //   }

  //   return returnStr;
}

export function getQueryVariable(variable) {
  if(!window||!window.location) return 
  let query = window.location.search.substring(1);
  let vars = query.split("&");
  for (let i=0;i<vars.length;i++) {
    let pair = vars[i].split("=");
    if(pair[0] == variable){return pair[1];}
  }
  return(false);
}

/**
 * id="main" ref="main"
 * getComponentSize('main', this).then(size=>{
 */
export function getComponentSize(selector, page) {
  return new Promise((resolve, reject)=>{
    // #ifdef APP-NVUE
    const dom = weex.requireModule('dom')
    dom.getComponentRect(this.$refs[selector], option => {
      resolve(option.size||{})
    })
    // #endif
          
    // #ifndef APP-NVUE
    uni.createSelectorQuery().in(page).select('#'+selector).boundingClientRect(data => {
      resolve(data||{})
    }).exec();
    // #endif
  })
}


export function createNumberArray(length, start=0, step=1) {
  return Array.from({length: length}, (v,i)=>i*step+start)
}
export function createTimeoutPromise(timeout=1000) {
  return new Promise(resolve=>{
    setTimeout(()=>resolve(), timeout)
  })
}
export async function createPollWork(work, count=1, waitTime, progress, waitTimeStep=0) {
  let arr = createNumberArray(count)
  let ret
  for(let i of arr) {
    try{
      ret = await work(i)
      return ret
    }catch(e) {
      if(waitTime) await createTimeoutPromise(waitTime)
      waitTime = waitTime+waitTimeStep
      await progress&&progress(i, count, e)
    }
  }
  throw 'timeout'
}


function randomArray(array = []) {
  // 原理是sort排序,Math.random()产生0<= x < 1之间的数,会导致x-0.05大于或者小于0
  return array.sort(() => Math.random() - 0.5)
}

/**
* @description 格式化时间
* @param {String|Number} dateTime 需要格式化的时间戳
* @param {String} fmt 格式化规则 yyyy:mm:dd|yyyy:mm|yyyy年mm月dd日|yyyy年mm月dd日 hh时MM分等,可自定义组合 默认yyyy-mm-dd
* @returns {string} 返回格式化后的字符串
*/
export function timeFormat(dateTime = null, fmt = 'yyyy-mm-dd') {
  // 如果为null,则格式化当前时间
  if (!dateTime) dateTime = Number(new Date())
  // 如果dateTime长度为10或者13，则为秒和毫秒的时间戳，如果超过13位，则为其他的时间格式
  if (dateTime.toString().length == 10) dateTime *= 1000
  const date = new Date(dateTime)
  let ret
  const opt = {
      'y+': date.getFullYear().toString(), // 年
      'm+': (date.getMonth() + 1).toString(), // 月
      'd+': date.getDate().toString(), // 日
      'h+': date.getHours().toString(), // 时
      'M+': date.getMinutes().toString(), // 分
      's+': date.getSeconds().toString() // 秒
      // 有其他格式化字符需求可以继续添加，必须转化成字符串
  }
  for (const k in opt) {
      ret = new RegExp(`(${k})`).exec(fmt)
      if (ret) {
          fmt = fmt.replace(ret[1], (ret[1].length == 1) ? (opt[k]) : (opt[k].padStart(ret[1].length, '0')))
      }
  }
  return fmt
}

/**
* @description 时间戳转为多久之前
* @param {String|Number} timestamp 时间戳
* @param {String|Boolean} format 
* 格式化规则如果为时间格式字符串，超出一定时间范围，返回固定的时间格式；
* 如果为布尔值false，无论什么时间，都返回多久以前的格式
* @returns {string} 转化后的内容
*/
export function timeFrom(timestamp = null, format = 'yyyy-mm-dd') {
  if (timestamp == null) timestamp = Number(new Date())
  timestamp = parseInt(timestamp)
  // 判断用户输入的时间戳是秒还是毫秒,一般前端js获取的时间戳是毫秒(13位),后端传过来的为秒(10位)
  if (timestamp.toString().length == 10) timestamp *= 1000
  let timer = (new Date()).getTime() - timestamp
  timer = parseInt(timer / 1000)
  // 如果小于5分钟,则返回"刚刚",其他以此类推
  let tips = ''
  switch (true) {
  case timer < 300:
      tips = '刚刚'
      break
  case timer >= 300 && timer < 3600:
      tips = `${parseInt(timer / 60)}分钟前`
      break
  case timer >= 3600 && timer < 86400:
      tips = `${parseInt(timer / 3600)}小时前`
      break
  case timer >= 86400 && timer < 2592000:
      tips = `${parseInt(timer / 86400)}天前`
      break
  default:
      // 如果format为false，则无论什么时间戳，都显示xx之前
      if (format === false) {
          if (timer >= 2592000 && timer < 365 * 86400) {
              tips = `${parseInt(timer / (86400 * 30))}个月前`
          } else {
              tips = `${parseInt(timer / (86400 * 365))}年前`
          }
      } else {
          tips = timeFormat(timestamp, format)
      }
  }
  return tips
}

export function toSnakeCase(str){
  return str.replace(/[A-Z]/g, letter => `_${letter.toLowerCase()}`)
}

export function getHTMLImage(str) {
  if(!str) return
  let ret = str.match('<img.*src=\"(.*?)\"')
  return ret&&ret[1]||''
}

export function getHTMLDesc(str, length=50) {
  if(!str) return
  let ret = str.slice(0,500).replaceAll(/<.*?>/ig, '')
  return ret.slice(0,length)
}